package io.sundial.console;

import io.httpdoc.spring.boot.EnableHttpdoc;
import io.sundial.conversion.impl.JavaConverter;
import io.sundial.conversion.jackson.JsonConverter;
import io.sundial.conversion.jackson.XmlConverter;
import io.sundial.conversion.jackson.YmlConverter;
import io.sundial.coordination.curator.CuratorCoordinator;
import io.sundial.core.context.Context;
import io.sundial.core.event.EventSupport;
import io.sundial.core.lifecycle.exception.InitializingException;
import io.sundial.planning.quartz.QuartzPlanner;
import io.sundial.protocol.impl.SundialProtocol;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

/**
 * 控制台应用
 *
 * @author Payne 646742615@qq.com
 * 2019/1/3 12:03
 */
@EnableHttpdoc(packages = "io.sundial", httpdoc = "Exchange+", version = "1.0.0")
@EnableJpaAuditing
@SpringBootApplication(scanBasePackages = "io.sundial.console")
public class ConsoleApplication {

    public static void main(String... args) {
        SpringApplication.run(ConsoleApplication.class, args);
    }

    @Bean
    public UnexpectedExceptionHandler unexpectedExceptionHandler() {
        return new UnexpectedExceptionHandler();
    }

    @Bean
    public ValidationExceptionHandler validationExceptionHandler() {
        return new ValidationExceptionHandler();
    }

    @Bean
    public QuartzPlanner quartzPlanner(Context context) throws InitializingException {
        QuartzPlanner planner = new QuartzPlanner();
        planner.initialize(context);
        return planner;
    }

    @Bean
    public EventSupport eventSupport() {
        return new EventSupport();
    }

    @Bean
    public Scheduler quartzScheduler() throws SchedulerException {
        StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
        return schedulerFactory.getScheduler();
    }

    @Bean
    public CuratorFramework curatorFramework() {
        return CuratorFrameworkFactory.builder()
                .connectString("localhost:2181")
                .retryPolicy(new ExponentialBackoffRetry(1000, 10, 10 * 1000))
                .namespace("sundial")
                .build();
    }

    @Bean
    public CuratorCoordinator curatorCoordinator(Context context) throws InitializingException {
        CuratorCoordinator coordinator = new CuratorCoordinator();
        coordinator.initialize(context);
        return coordinator;
    }

    @Bean
    public JavaConverter javaConverter() {
        return new JavaConverter();
    }

    @Bean
    public JsonConverter jsonConverter() {
        return new JsonConverter();
    }

    @Bean
    public XmlConverter xmlConverter() {
        return new XmlConverter();
    }

    @Bean
    public YmlConverter ymlConverter() {
        return new YmlConverter();
    }

    @Bean
    public SundialProtocol sundialProtocol(Context context) throws InitializingException {
        SundialProtocol sundialProtocol = new SundialProtocol();
        sundialProtocol.initialize(context);
        return sundialProtocol;
    }
}
